module cryptdap(clk,rst,keyadsel,mixsel,reginsel,shiftsel,wrregen,din,roundkey,dout);

output [31:0] dout;//将128位明文/密文，按照32位串行输出
input clk,wrregen,mixsel,reginsel,shiftsel;
input [1:0] keyadsel;
input [31:0] din;//串行接收128位明文/密文
input [127:0] roundkey;//接收128位的密钥
input rst;

wire [127:0] outtxt;
wire [31:0] reg0in,reg1in,reg2in,reg3in;
wire [7:0] sb0out,sb1out,sb2out,sb3out,sb4out,sb5out,sb6out,sb7out;
wire [7:0] sb8out,sb9out,sb10out,sb11out,sb12out,sb13out,sb14out,sb15out;
wire [7:0] invsb0out,invsb1out,invsb2out,invsb3out,invsb4out,invsb5out,invsb6out,invsb7out;
wire [7:0] invsb8out,invsb9out,invsb10out,invsb11out,invsb12out,invsb13out,invsb14out,invsb15out;
wire [7:0] c0,c1,c2,c3,c4,c5,c6,c7,c8,c9,c10,c11,c12,c13,c14,c15;
wire [7:0] d0,d1,d2,d3,d4,d5,d6,d7,d8,d9,d10,d11,d12,d13,d14,d15;
wire [7:0] f0,f1,f2,f3,f4,f5,f6,f7,f8,f9,f10,f11,f12,f13,f14,f15;
wire [7:0] g0,g1,g2,g3,g4,g5,g6,g7,g8,g9,g10,g11,g12,g13,g14,g15;
wire [7:0] m0,m1,m2,m3,m4,m5,m6,m7,m8,m9,m10,m11,m12,m13,m14,m15;
wire [7:0] f002,f003,f009,f00b,f00d,f00e;
wire [7:0] f102,f103,f109,f10b,f10d,f10e;
wire [7:0] f202,f203,f209,f20b,f20d,f20e;
wire [7:0] f302,f303,f309,f30b,f30d,f30e;
wire [7:0] f402,f403,f409,f40b,f40d,f40e;
wire [7:0] f502,f503,f509,f50b,f50d,f50e;
wire [7:0] f602,f603,f609,f60b,f60d,f60e;
wire [7:0] f702,f703,f709,f70b,f70d,f70e;
wire [7:0] f802,f803,f809,f80b,f80d,f80e;
wire [7:0] f902,f903,f909,f90b,f90d,f90e;
wire [7:0] f1002,f1003,f1009,f100b,f100d,f100e;
wire [7:0] f1102,f1103,f1109,f110b,f110d,f110e;
wire [7:0] f1202,f1203,f1209,f120b,f120d,f120e;
wire [7:0] f1302,f1303,f1309,f130b,f130d,f130e;
wire [7:0] f1402,f1403,f1409,f140b,f140d,f140e;
wire [7:0] f1502,f1503,f1509,f150b,f150d,f150e;
wire [127:0] d,e,g,regin;

//一个密文分组是16个字节块，所以需要16个S盒
sbox_mux  sbox_mux0(outtxt[127:120],sb0out);//从左到右，从上到下排成4*4矩阵
sbox_mux  sbox_mux1(outtxt[119:112],sb1out);//每8位，在sbox_mux中进行替换 
sbox_mux  sbox_mux2(outtxt[111:104],sb2out);
sbox_mux  sbox_mux3(outtxt[103:96],sb3out);
sbox_mux  sbox_mux4(outtxt[95:88],sb4out);
sbox_mux  sbox_mux5(outtxt[87:80],sb5out);
sbox_mux  sbox_mux6(outtxt[79:72],sb6out);
sbox_mux  sbox_mux7(outtxt[71:64],sb7out);
sbox_mux  sbox_mux8(outtxt[63:56],sb8out);
sbox_mux  sbox_mux9(outtxt[55:48],sb9out);
sbox_mux  sbox_mux10(outtxt[47:40],sb10out);
sbox_mux  sbox_mux11(outtxt[39:32],sb11out);
sbox_mux  sbox_mux12(outtxt[31:24],sb12out);
sbox_mux  sbox_mux13(outtxt[23:16],sb13out);
sbox_mux  sbox_mux14(outtxt[15:8],sb14out);
sbox_mux  sbox_mux15(outtxt[7:0],sb15out);

invsbox_mux  invsbox_mux0(outtxt[127:120],invsb0out);//解密时的逆S盒字节代换
invsbox_mux  invsbox_mux1(outtxt[119:112],invsb1out);
invsbox_mux  invsbox_mux2(outtxt[111:104],invsb2out);
invsbox_mux  invsbox_mux3(outtxt[103:96],invsb3out);
invsbox_mux  invsbox_mux4(outtxt[95:88],invsb4out);
invsbox_mux  invsbox_mux5(outtxt[87:80],invsb5out);
invsbox_mux  invsbox_mux6(outtxt[79:72],invsb6out);
invsbox_mux  invsbox_mux7(outtxt[71:64],invsb7out);
invsbox_mux  invsbox_mux8(outtxt[63:56],invsb8out);
invsbox_mux  invsbox_mux9(outtxt[55:48],invsb9out);
invsbox_mux  invsbox_mux10(outtxt[47:40],invsb10out);
invsbox_mux  invsbox_mux11(outtxt[39:32],invsb11out);
invsbox_mux  invsbox_mux12(outtxt[31:24],invsb12out);
invsbox_mux  invsbox_mux13(outtxt[23:16],invsb13out);
invsbox_mux  invsbox_mux14(outtxt[15:8],invsb14out);
invsbox_mux  invsbox_mux15(outtxt[7:0],invsb15out);

//第十轮解密
assign m0=invsb0out^roundkey[127:120];//进行逆行移位，和轮密钥异或
assign m1=invsb13out^roundkey[119:112];
assign m2=invsb10out^roundkey[111:104];
assign m3=invsb7out^roundkey[103:96];
assign m4=invsb4out^roundkey[95:88];
assign m5=invsb1out^roundkey[87:80];
assign m6=invsb14out^roundkey[79:72];
assign m7=invsb11out^roundkey[71:64];
assign m8=invsb8out^roundkey[63:56];
assign m9=invsb5out^roundkey[55:48];
assign m10=invsb2out^roundkey[47:40];
assign m11=invsb15out^roundkey[39:32];
assign m12=invsb12out^roundkey[31:24];
assign m13=invsb9out^roundkey[23:16];
assign m14=invsb6out^roundkey[15:8];
assign m15=invsb3out^roundkey[7:0];

mux21_8  mux21_8_0(mixsel,sb0out,m0,f0);//选择信号决定输出的是加密过程还是解密过程
mux21_8  mux21_8_1(mixsel,sb1out,m1,f1);//sb0out是加密时，字节代换后的值
mux21_8  mux21_8_2(mixsel,sb2out,m2,f2);//m0是解密时，逆字节替换、逆行移位、轮密钥加后的值
mux21_8  mux21_8_3(mixsel,sb3out,m3,f3);
mux21_8  mux21_8_4(mixsel,sb4out,m4,f4);
mux21_8  mux21_8_5(mixsel,sb5out,m5,f5);
mux21_8  mux21_8_6(mixsel,sb6out,m6,f6);
mux21_8  mux21_8_7(mixsel,sb7out,m7,f7);
mux21_8  mux21_8_8(mixsel,sb8out,m8,f8);
mux21_8  mux21_8_9(mixsel,sb9out,m9,f9);
mux21_8  mux21_8_10(mixsel,sb10out,m10,f10);
mux21_8  mux21_8_11(mixsel,sb11out,m11,f11);
mux21_8  mux21_8_12(mixsel,sb12out,m12,f12);
mux21_8  mux21_8_13(mixsel,sb13out,m13,f13);
mux21_8  mux21_8_14(mixsel,sb14out,m14,f14);
mux21_8  mux21_8_15(mixsel,sb15out,m15,f15);

byte0203 byte0203_0(f0,f002,f003);//加密，把每个字节的02/03乘输出
byte0203 byte0203_1(f1,f102,f103);//此时f0为sb0out
byte0203 byte0203_2(f2,f202,f203);
byte0203 byte0203_3(f3,f302,f303);
byte0203 byte0203_4(f4,f402,f403);
byte0203 byte0203_5(f5,f502,f503);
byte0203 byte0203_6(f6,f602,f603);
byte0203 byte0203_7(f7,f702,f703);
byte0203 byte0203_8(f8,f802,f803);
byte0203 byte0203_9(f9,f902,f903);
byte0203 byte0203_10(f10,f1002,f1003);
byte0203 byte0203_11(f11,f1102,f1103);
byte0203 byte0203_12(f12,f1202,f1203);
byte0203 byte0203_13(f13,f1302,f1303);
byte0203 byte0203_14(f14,f1402,f1403);
byte0203 byte0203_15(f15,f1502,f1503);

byte9bde byte9bde_0(f0,f002,f003,f009,f00b,f00d,f00e);//解密，
byte9bde byte9bde_1(f1,f102,f103,f109,f10b,f10d,f10e);//把每个字节的09/0b/0d/0e结果都输出
byte9bde byte9bde_2(f2,f202,f203,f209,f20b,f20d,f20e);//此时f0为m0
byte9bde byte9bde_3(f3,f302,f303,f309,f30b,f30d,f30e);
byte9bde byte9bde_4(f4,f402,f403,f409,f40b,f40d,f40e);
byte9bde byte9bde_5(f5,f502,f503,f509,f50b,f50d,f50e);
byte9bde byte9bde_6(f6,f602,f603,f609,f60b,f60d,f60e);
byte9bde byte9bde_7(f7,f702,f703,f709,f70b,f70d,f70e);
byte9bde byte9bde_8(f8,f802,f803,f809,f80b,f80d,f80e);
byte9bde byte9bde_9(f9,f902,f903,f909,f90b,f90d,f90e);
byte9bde byte9bde_10(f10,f1002,f1003,f1009,f100b,f100d,f100e);
byte9bde byte9bde_11(f11,f1102,f1103,f1109,f110b,f110d,f110e);
byte9bde byte9bde_12(f12,f1202,f1203,f1209,f120b,f120d,f120e);
byte9bde byte9bde_13(f13,f1302,f1303,f1309,f130b,f130d,f130e);
byte9bde byte9bde_14(f14,f1402,f1403,f1409,f140b,f140d,f140e);
byte9bde byte9bde_15(f15,f1502,f1503,f1509,f150b,f150d,f150e);

//encryption transformation,include 0th round and 10th round decryption transformation
assign c0=f002^f503^sb10out^sb15out;//行移位加列混合同时运算
mux41_8  mux41_8_0(keyadsel,outtxt[127:120],c0,sb0out,invsb0out,d0);
//加密时第0轮时，选择outtxt，进行轮密钥加；1-9轮，选择c0；
//第10轮，选择sb0out，进行行移位；
//解密时，第0轮同理；第10轮同理
assign c1=sb0out^f502^f1003^sb15out;
mux41_8  mux41_8_1(keyadsel,outtxt[119:112],c1,sb5out,invsb13out,d1);
assign c2=sb0out^sb5out^f1002^f1503;
mux41_8  mux41_8_2(keyadsel,outtxt[111:104],c2,sb10out,invsb10out,d2);
assign c3=f003^sb5out^sb10out^f1502;
mux41_8  mux41_8_3(keyadsel,outtxt[103:96],c3,sb15out,invsb7out,d3);
assign c4=f402^f903^sb14out^sb3out;
mux41_8  mux41_8_4(keyadsel,outtxt[95:88],c4,sb4out,invsb4out,d4);
assign c5=sb4out^f902^f1403^sb3out;
mux41_8  mux41_8_5(keyadsel,outtxt[87:80],c5,sb9out,invsb1out,d5);
assign c6=sb4out^sb9out^f1402^f303;
mux41_8  mux41_8_6(keyadsel,outtxt[79:72],c6,sb14out,invsb14out,d6);
assign c7=f403^sb9out^sb14out^f302;
mux41_8  mux41_8_7(keyadsel,outtxt[71:64],c7,sb3out,invsb11out,d7);
assign c8=f802^f1303^sb2out^sb7out;
mux41_8  mux41_8_8(keyadsel,outtxt[63:56],c8,sb8out,invsb8out,d8);
assign c9=sb8out^f1302^f203^sb7out;
mux41_8  mux41_8_9(keyadsel,outtxt[55:48],c9,sb13out,invsb5out,d9);
assign c10=sb8out^sb13out^f202^f703;
mux41_8  mux41_8_10(keyadsel,outtxt[47:40],c10,sb2out,invsb2out,d10);
assign c11=f803^sb13out^sb2out^f702;
mux41_8  mux41_8_11(keyadsel,outtxt[39:32],c11,sb7out,invsb15out,d11);
assign c12=f1202^f103^sb6out^sb11out;
mux41_8  mux41_8_12(keyadsel,outtxt[31:24],c12,sb12out,invsb12out,d12);
assign c13=sb12out^f102^f603^sb11out;
mux41_8  mux41_8_13(keyadsel,outtxt[23:16],c13,sb1out,invsb9out,d13);
assign c14=sb12out^sb1out^f602^f1103;
mux41_8  mux41_8_14(keyadsel,outtxt[15:8],c14,sb6out,invsb6out,d14);
assign c15=f1203^sb1out^sb6out^f1102;
mux41_8  mux41_8_15(keyadsel,outtxt[7:0],c15,sb11out,invsb3out,d15);
assign d={d0,d1,d2,d3,d4,d5,d6,d7,d8,d9,d10,d11,d12,d13,d14,d15};
assign e=d^roundkey;//进行轮密钥加

//decryption 1-9th round transformation
assign g0=f00e^f10b^f20d^f309;//因为上面第十轮已经实现了除逆列混合外所有的功能
assign g1=f009^f10e^f20b^f30d;//所以此处在前面基础上进行逆列混合
assign g2=f00d^f109^f20e^f30b;
assign g3=f00b^f10d^f209^f30e;
assign g4=f40e^f50b^f60d^f709;
assign g5=f409^f50e^f60b^f70d;
assign g6=f40d^f509^f60e^f70b;
assign g7=f40b^f50d^f609^f70e;
assign g8=f80e^f90b^f100d^f1109;
assign g9=f809^f90e^f100b^f110d;
assign g10=f80d^f909^f100e^f110b;
assign g11=f80b^f90d^f1009^f110e;
assign g12=f120e^f130b^f140d^f1509;
assign g13=f1209^f130e^f140b^f150d;
assign g14=f120d^f1309^f140e^f150b;
assign g15=f120b^f130d^f1409^f150e;
assign g={g0,g1,g2,g3,g4,g5,g6,g7,g8,g9,g10,g11,g12,g13,g14,g15};

//resultreg input selection
//0th-10th round encryption transformation,regin=e;
//0th round and 10th round decryption transformation,regin=e;
//1-9th round decryption transformation,regin=g.
mux21_128  mux21_128_0(reginsel,e,g,regin);

//register shift-right to input data and output result 8bits per cycle
//完美实现数据右移
mux21_32  mux21_32_0(shiftsel,regin[127:96],din,reg0in);
mux21_32  mux21_32_1(shiftsel,regin[95:64],outtxt[127:96],reg1in);
mux21_32  mux21_32_2(shiftsel,regin[63:32],outtxt[95:64],reg2in);
mux21_32  mux21_32_3(shiftsel,regin[31:0],outtxt[63:32],reg3in);

reg_32   reg_32_0(clk,rst,wrregen,reg0in,outtxt[127:96]);
reg_32   reg_32_1(clk,rst,wrregen,reg1in,outtxt[95:64]);
reg_32   reg_32_2(clk,rst,wrregen,reg2in,outtxt[63:32]);
reg_32   reg_32_3(clk,rst,wrregen,reg3in,outtxt[31:0]);

assign dout=outtxt[31:0];



endmodule
